import React, { useEffect, useRef, useMemo } from 'react'
import { observer } from '@formily/react'
import { DnFC, useNodeIdProps, useTreeNode } from '@designable/react'
import { TreeNode, createBehavior, createResource } from '@designable/core'
import { AllSchemas } from '../../schemas'
import { AllLocales } from '../../locales'
import { createVoidFieldSchema } from '../Field'
import { LoadTemplate } from '../../common/LoadTemplate'
import { Descriptions as AntdDescriptions, Space, Tag } from 'antd'
import { Button } from '../../customComponents'
import { useT } from '@designable/event-system'
import { AntdDescriptionsWrapper } from '../../customComponents/Descriptions'

const parseItems = (parent: TreeNode) => {
  const items: TreeNode[] = []
  parent.children.forEach((child) => {
    if (
      child &&
      child.props &&
      child.props['x-component'] === 'Descriptions.Item'
    ) {
      items.push(child)
    }
  })
  return items
}

export const Descriptions: DnFC<
  React.ComponentProps<typeof AntdDescriptions> & { buttons?: any[] }
> = observer((props) => {
  const nodeIdProps = useNodeIdProps()
  const node = useTreeNode()
  const itemNodes = parseItems(node)

  const items = itemNodes.map((itemNode, index) => {
    const compProps = itemNode.props['x-component-props'] || {}
    const label = compProps.label || `Item ${index + 1}`
    const span = compProps.span
    const children = compProps.children
    return { key: itemNode.id, label, span, node: itemNode, children }
  })

  const InnerCom: React.FC<{
    key: string
    label?: string
    span?: number
    children?: React.ReactNode | string
    node: TreeNode
  }> = ({ node, children }) => {
    const nodeIdProps = useNodeIdProps(node)
    const markerRef = useRef<HTMLDivElement | null>(null)

    useEffect(() => {
      const marker = markerRef.current
      if (!marker) return
      const container = marker.closest(
        '.ant-descriptions-item'
      ) as HTMLElement | null
      if (!container) return

      Object.entries(nodeIdProps).forEach(([name, value]) => {
        if (value == null) return
        if (name === 'className') {
          container.classList.add(String(value))
        } else {
          container.setAttribute(name, String(value))
        }
      })

      return () => {
        Object.entries(nodeIdProps).forEach(([name, value]) => {
          if (value == null) return
          if (name === 'className') {
            container.classList.remove(String(value))
          } else {
            container.removeAttribute(name)
          }
        })
      }
    }, [nodeIdProps])
    return <div ref={markerRef}>{children}</div>
  }

  // 渲染 extra 按钮列表

  return (
    <div {...nodeIdProps}>
      <AntdDescriptionsWrapper {...props}>
        {items.map((it) => (
          <AntdDescriptions.Item key={it.key} label={it.label} span={it.span}>
            <InnerCom {...it} />
          </AntdDescriptions.Item>
        ))}
      </AntdDescriptionsWrapper>
      <LoadTemplate
        actions={[
          {
            title: '添加项',
            icon: 'AddPanel',
            onClick: () => {
              const nextIndex = itemNodes.length + 1
              const item = new TreeNode({
                componentName: 'Field',
                props: {
                  type: 'void',
                  'x-component': 'Descriptions.Item',
                  'x-component-props': {
                    label: `Item ${nextIndex}`,
                  },
                },
              })
              node.append(item)
            },
          },
        ]}
      />
    </div>
  )
})

Descriptions.Behavior = createBehavior(
  {
    name: 'Descriptions',
    extends: ['Field'],
    selector: (node) => node.props['x-component'] === 'Descriptions',
    designerProps: {
      droppable: true,
      allowAppend: (target, source) =>
        target.children.length === 0 ||
        source.every((n) => n.props['x-component'] === 'Descriptions.Item'),
      propsSchema: createVoidFieldSchema(AllSchemas.Descriptions),
    },
    designerLocales: AllLocales.Descriptions,
  },
  {
    name: 'Descriptions.Item',
    extends: ['Field'],
    selector: (node) => node.props['x-component'] === 'Descriptions.Item',
    designerProps: {
      droppable: true,
      allowDrop: (node) => node.props['x-component'] === 'Descriptions',
      propsSchema: createVoidFieldSchema(AllSchemas.Descriptions.Item),
    },
    designerLocales: AllLocales.DescriptionsItem,
  }
)

Descriptions.Resource = createResource({
  icon: 'Descriptions',
  elements: [
    {
      componentName: 'Field',
      props: {
        type: 'void',
        title: 'Descriptions',
        'x-component': 'Descriptions',
        'x-component-props': {},
      },
    },
  ],
})
